`include "PRV564Config.v"
`include "PRV564Define.v"
//////////////////////////////////////////////////////////////////////////////////////////////////
//  Date    : 2021                                                                              //
//  Author  : Jack.Pan                                                                          //
//  Desc    : Load And Store Unit For PRV564 processor                                          //
//  Version : 0.0(Original Verision)                                                            //
//////////////////////////////////////////////////////////////////////////////////////////////////
module LSU
#(parameter DTLB_FIBID = 8'h02)
(
//-------------------Global Signals------------------------
    input  wire             LSUi_CLK,
    input  wire             LSUi_ARST,
    input  wire             LSUi_Flush,
    input wire              LSUi_fencevma,
    input wire              LSUi_fence,
//-----------------Modify permit signal-----------------------
    input wire              LSUi_ModifyPermit,
    input wire [7:0]        LSUi_ModifyPermitID,
//-----------------------CSR value in--------------------------
    input  wire [43:0]      CSR_satpppn,
    input  wire [3:0]       CSR_satpmode,
    input  wire [1:0]       CSR_priv,
    input  wire             CSR_InhibitDcache,
    input  wire             CSR_DCacheWT,
    input  wire             CSR_mxr,
    input  wire             CSR_sum,
//------------------Pipline Input Signals------------------
    input  wire             PIP_LSUi_MSC_valid,         //操作有效
    input  wire [7:0]       PIP_LSUi_Opcode,            //LSU操作码
    input  wire [1:0]       PIP_LSUi_OpInfo,            //LSU操作信息
    input  wire [3:0]       PIP_LSUi_OpSize, 
    input  wire [7:0]       PIP_LSUi_INFO_itag,
    input  wire [1:0]       PIP_LSUi_INFO_priv,         //权限
    input  wire [`XLEN-1:0] PIP_LSUi_INFO_pc,           //Instruction Infomation: PC value
    input  wire             PIP_LSUi_INFO_unpage,       //强制禁用分页
    input  wire [`XLEN-1:0] PIP_LSUi_DATA_ds1,
    input  wire [`XLEN-1:0] PIP_LSUi_DATA_ds2,
    output  wire            PIP_LSUo_FC_ready,
//--------------------Pipline Output Signals----------------
    output                  PIP_LSUo_MSC_valid,
    output                  PIP_LSUo_MSC_LoadPageFlt ,
    output                  PIP_LSUo_MSC_LoadAccFlt  ,
    output                  PIP_LSUo_MSC_LoadAddrMis ,
    output                  PIP_LSUo_MSC_StorePageFlt,
    output                  PIP_LSUo_MSC_StoreAccFlt ,
    output                  PIP_LSUo_MSC_StoreAddrMis,
    output wire             PIP_LSUo_INFO_ci,
    output wire [7:0]       PIP_LSUo_INFO_itag,
    output wire [`XLEN-1:0] PIP_LSUo_INFO_pc,
    output wire [1:0]       PIP_LSUo_INFO_priv,
    output     [`XLEN-1:0]  PIP_LSUo_DATA_data1,        //data1 output, for GPR write back
    output wire [`XLEN-1:0] PIP_LSUo_DATA_data2,        //data2 output, for CSR write back
    input wire              PIP_LSUi_FC_ready,           //write back is ready to go
    
//--------------------FIB1--------------------------
    output  wire            DTLB_FIBo_WREN,        //write to FIB0 enable
    output  wire            DTLB_FIBo_REQ,         //request FIB0 trans
    input   wire            DTLB_FIBi_ACK,         //request acknowledge
    input   wire            DTLB_FIBi_FULL,        //FIB0 FIFO full
    output  wire [7:0]      DTLB_FIBo_ID,
    output  wire [7:0]      DTLB_FIBo_CMD,
    output  wire [3:0]      DTLB_FIBo_BURST,
    output  wire [3:0]      DTLB_FIBo_SIZE,
    output  wire [`XLEN-1:0]DTLB_FIBo_ADDR,      
    output  wire [`XLEN-1:0]DTLB_FIBo_DATA,
    input   wire [7:0]      DTLB_FIBi_ID,
    input   wire [7:0]      DTLB_FIBi_RPL,
    input   wire            DTLB_FIBi_V,
    input   wire [`XLEN-1:0]DTLB_FIBi_DATA,
//------------------------Cache port--------------------
    output wire             LSUo_AQ_V,          //add a new access to Access Queue
    output wire [7:0]       LSUo_AQ_ID,         //new access's ID
    output wire [7:0]       LSUo_AQ_CMD,        //command and
    output wire             LSUo_AQ_CI,         //cache is inhibit
    output wire             LSUo_AQ_WT,         //write through is needed
    output wire [15:0]      LSUo_AQ_BSEL,       //Byte select
    output wire [127:0]     LSUo_AQ_WDATA,      //write data (or exchange data)
    output wire [`XLEN-1:0] LSUo_AQ_ADDR,
    input wire              LSUi_AQ_FULL,
    input wire              LSUi_RQ_V,
    input wire [7:0]        LSUi_RQ_ID,
    input wire              LSUi_RQ_WRERR,
    input wire              LSUi_RQ_RDERR,
    input wire              LSUi_RQ_RDY,
    input wire [127:0]      LSUi_RQ_RDATA,
    output wire             LSUo_RQ_ACK
);
//---------------------ATU connect to Access Table-------------
//                   [  write port  ]       [ read port ]
    wire              Tablei_WREN,          Tablei_RDEN;
    wire [7:0]        Tablei_WID,           Tablei_RID;
    wire                                    Tablei_Remove;
    wire                                    Tableo_V;
    wire [`XLEN-1:0]  Tablei_ADDR,          Tableo_ADDR;
    wire [`XLEN-1:0]  Tablei_PC,            Tableo_PC;
    wire [7:0]        Tablei_ITAG,          Tableo_ITAG;
    wire [1:0]        Tablei_priv,          Tableo_priv;
    wire [7:0]        Tablei_opcode,        Tableo_opcode;
    wire [1:0]        Tablei_opinfo,        Tableo_opinfo;
    wire [3:0]        Tablei_opsize,        Tableo_opsize;
    wire              Tablei_ci,            Tableo_ci;
    wire              Tablei_InstPageFlt,   Tableo_InstPageFlt;
    wire              Tablei_InstAddrMis,   Tableo_InstAddrmis;
    wire              Tablei_LoadPageFlt,   Tableo_LoadPageFlt;
    wire              Tablei_LoadAddrMis,   Tableo_LoadAddrMis;
    wire              Tablei_StorePageFlt,  Tableo_StorePageFlt;
    wire              Tablei_StoreAddreMis, Tableo_StoreAddrMis;
    wire              Tableo_FULL;

//------------------------------ATU---------------------------------------
ATU#(
    .FIB_ID(DTLB_FIBID),                                          //FIB ID = 00h
    .TLB_entry_NUM (`DTLB_entry_NUM)
) LSU_ATU(
    .ATUi_CLK                       (LSUi_CLK),
    .ATUi_ARST                      (LSUi_ARST),
    .ATUi_Flush                     (LSUi_Flush),
    .ATUi_ModifyPermit              (LSUi_ModifyPermit),
    .ATUi_ModifyPermitID            (LSUi_ModifyPermitID),
    .ATUi_TLBrefersh                (LSUi_fencevma),
    .ATUi_CacheRefersh              (LSUi_fence),
    .ATUi_CSR_CacheInhibit          (CSR_InhibitDcache),
    .ATUi_CSR_CacheWT               (CSR_DCacheWT),                 //I-Cache dont need write through mode
    .ATUi_CSR_mxr                   (CSR_mxr),
    .ATUi_CSR_sum                   (CSR_sum),
    .ATUi_CSR_satpmode              (CSR_satpmode),
    .ATUi_CSR_satpppn               (CSR_satpppn),
    .PIP_ATUi_MSC_valid             (PIP_LSUi_MSC_valid),
    .PIP_ATUi_Opcode                (PIP_LSUi_Opcode),
    .PIP_ATUi_OpInfo                (PIP_LSUi_OpInfo),
    .PIP_ATUi_OpSize                (PIP_LSUi_OpSize),
    .PIP_ATUi_INFO_ITAG             (PIP_LSUi_INFO_itag),
    .PIP_ATUi_INFO_priv             (PIP_LSUi_INFO_priv),
    .PIP_ATUi_INFO_unpage           (PIP_LSUi_INFO_unpage),
    .PIP_ATUi_INFO_PC               (PIP_LSUi_INFO_pc),     //指令地址转换时，VA和PC是一致的
    .PIP_ATUi_DATA_VA               (PIP_LSUi_DATA_ds1),
    .PIP_ATUi_DATA_ds2              (PIP_LSUi_DATA_ds2),
    .PIP_ATUo_FC_ready              (PIP_LSUo_FC_ready),
//------------------write to access table-----------------
    .Tablei_WREN                    (Tablei_WREN),
    .Tablei_WID                     (Tablei_WID),
    .Tablei_ADDR                    (Tablei_ADDR),
    .Tablei_PC                      (Tablei_PC),
    .Tablei_ITAG                    (Tablei_ITAG),
    .Tablei_priv                    (Tablei_priv),
    .Tablei_opcode                  (Tablei_opcode),
    .Tablei_opinfo                  (Tablei_opinfo),
    .Tablei_opsize                  (Tablei_opsize),
    .Tablei_ci                      (Tablei_ci),
    .Tablei_InstPageFlt             (Tablei_InstPageFlt),
    .Tablei_InstAddrMis             (Tablei_InstAddrMis),
    .Tablei_LoadPageFlt             (Tablei_LoadPageFlt),
    .Tablei_LoadAddrMis             (Tablei_LoadAddrMis),
    .Tablei_StorePageFlt            (Tablei_StorePageFlt),
    .Tablei_StoreAddreMis           (Tablei_StoreAddreMis),
    .Tableo_FULL                    (Tableo_FULL),
//------------------issue to access queue-----------------
    .ATUo_AQ_V                      (LSUo_AQ_V),
    .ATUo_AQ_ID                     (LSUo_AQ_ID),
    .ATUo_AQ_CMD                    (LSUo_AQ_CMD),
    .ATUo_AQ_CI                     (LSUo_AQ_CI),
    .ATUo_AQ_WT                     (LSUo_AQ_WT),
    .ATUo_AQ_BSEL                   (LSUo_AQ_BSEL),
    .ATUo_AQ_WDATA                  (LSUo_AQ_WDATA),
    .ATUo_AQ_ADDR                   (LSUo_AQ_ADDR),
    .ATUi_AQ_FULL                   (LSUi_AQ_FULL),
//------------------------ATU FIB interface-------------------------
    .ATUo_FIB_WREN                  (DTLB_FIBo_WREN),
    .ATUo_FIB_REQ                   (DTLB_FIBo_REQ),
    .ATUi_FIB_ACK                   (DTLB_FIBi_ACK),
    .ATUi_FIB_FULL                  (DTLB_FIBi_FULL),
    .ATUo_FIB_ID                    (DTLB_FIBo_ID),
    .ATUo_FIB_CMD                   (DTLB_FIBo_CMD),
    .ATUo_FIB_BURST                 (DTLB_FIBo_BURST),
    .ATUo_FIB_SIZE                  (DTLB_FIBo_SIZE),
    .ATUo_FIB_ADDR                  (DTLB_FIBo_ADDR),
    .ATUo_FIB_DATA                  (DTLB_FIBo_DATA),
    .ATUi_FIB_ID                    (DTLB_FIBi_ID),
    .ATUi_FIB_RPL                   (DTLB_FIBi_RPL),
    .ATUi_FIB_V                     (DTLB_FIBi_V),
    .ATUi_FIB_DATA                  (DTLB_FIBi_DATA)
);
//-----------------------------Access Table-------------------------------
AccessTable             AccessTable(
    .GLB_CLKi                       (LSUi_CLK),
    .GLB_SRSTi                      (LSUi_ARST | LSUi_Flush),
//------------------------Empty and FULL signals-----------------
    .Table_Full                     (Tableo_FULL),
    .Table_Empty                    (),             //Table为空信号不用
//-----------------------Access Table write port-----------------
    .Tablei_WREN                    (Tablei_WREN),
    .Tablei_WID                     (Tablei_WID),
    .Tablei_ADDR                    (Tablei_ADDR),
    .Tablei_PC                      (Tablei_PC),
    .Tablei_ITAG                    (Tablei_ITAG),
    .Tablei_priv                    (Tablei_priv),
    .Tablei_opcode                  (Tablei_opcode),
    .Tablei_opinfo                  (Tablei_opinfo),
    .Tablei_opsize                  (Tablei_opsize),
    .Tablei_ci                      (Tablei_ci),
    .Tablei_InstPageFlt             (Tablei_InstPageFlt),
    .Tablei_LoadPageFlt             (Tablei_LoadPageFlt),
    .Tablei_StorePageFlt            (Tablei_StorePageFlt),
    .Tablei_InstAddrmis             (Tablei_InstAddrMis),
    .Tablei_LoadAddrMis             (Tablei_LoadAddrMis),
    .Tablei_StoreAddrMis            (Tablei_StoreAddreMis),
//--------------------Access Table read port----------------------
    .Tablei_RDEN                    (Tablei_RDEN),
    .Tablei_RID                     (Tablei_RID),
    .Tablei_Remove                  (Tablei_Remove),
    .Tableo_V                       (Tableo_V),
    .Tableo_ADDR                    (Tableo_ADDR),
    .Tableo_PC                      (Tableo_PC),
    .Tableo_ITAG                    (Tableo_ITAG),
    .Tableo_priv                    (Tableo_priv),
    .Tableo_opcode                  (Tableo_opcode),
    .Tableo_opinfo                  (Tableo_opinfo),
    .Tableo_opsize                  (Tableo_opsize),
    .Tableo_ci                      (Tableo_ci),
    .Tableo_InstPageFlt             (Tableo_InstPageFlt),
    .Tableo_LoadPageFlt             (Tableo_LoadPageFlt),
    .Tableo_StorePageFlt            (Tableo_StorePageFlt),
    .Tableo_InstAddrmis             (Tableo_InstAddrmis),
    .Tableo_LoadAddrMis             (Tableo_LoadAddrMis),
    .Tableo_StoreAddrMis            (Tableo_StoreAddrMis)	
);
ResultUnit              ResultUnit(
//---------------Global signal-----------
    .RUi_CLK                        (LSUi_CLK),
    .RUi_ARST                       (LSUi_ARST),
    .RUi_Flush                      (LSUi_Flush),
//--------------Result Queue output------
    .RUi_RQ_V                       (LSUi_RQ_V),
    .RUi_RQ_ID                      (LSUi_RQ_ID),
    .RUi_RQ_WRERR                   (LSUi_RQ_WRERR),
    .RUi_RQ_RDERR                   (LSUi_RQ_RDERR),
    .RUi_RQ_RDY                     (LSUi_RQ_RDY),
    .RUi_RQ_RDATA                   (LSUi_RQ_RDATA),
    .RUo_RQ_ACK                     (LSUo_RQ_ACK),
//---------------Access Table------------
    .Tablei_RDEN                    (Tablei_RDEN),
    .Tablei_RID                     (Tablei_RID),
    .Tablei_Remove                  (Tablei_Remove),
    .Tableo_V                       (Tableo_V),
    .Tableo_ADDR                    (Tableo_ADDR),
    .Tableo_PC                      (Tableo_PC),
    .Tableo_ITAG                    (Tableo_ITAG),
    .Tableo_priv                    (Tableo_priv),
    .Tableo_opcode                  (Tableo_opcode),
    .Tableo_opinfo                  (Tableo_opinfo),
    .Tableo_opsize                  (Tableo_opsize),
    .Tableo_ci                      (Tableo_ci),
    .Tableo_InstPageFlt             (Tableo_InstPageFlt),
    .Tableo_LoadPageFlt             (Tableo_LoadPageFlt),
    .Tableo_StorePageFlt            (Tableo_StorePageFlt),
    .Tableo_InstAddrmis             (Tableo_InstAddrmis),
    .Tableo_LoadAddrMis             (Tableo_LoadAddrMis),
    .Tableo_StoreAddrMis            (Tableo_StoreAddrMis),	
//----------------Result output---------------
    .RUo_valid                      (PIP_LSUo_MSC_valid),
    .RUo_InstPageFlt                (),
    .RUo_InstAddrMis                (),
    .RUo_InstAccFlt                 (),
    .RUo_LoadPageFlt                (PIP_LSUo_MSC_LoadPageFlt),
    .RUo_LoadAddrMis                (PIP_LSUo_MSC_LoadAddrMis),
    .RUo_LoadAccFlt                 (PIP_LSUo_MSC_LoadAccFlt),
    .RUo_StorePageFlt               (PIP_LSUo_MSC_StorePageFlt),
    .RUo_StoreAddrMis               (PIP_LSUo_MSC_StoreAddrMis),
    .RUo_StoreAccFlt                (PIP_LSUo_MSC_StoreAccFlt),
    .RUo_ci                         (PIP_LSUo_INFO_ci),
    .RUo_ITAG                       (PIP_LSUo_INFO_itag),
    .RUo_priv                       (PIP_LSUo_INFO_priv),
    .RUo_PC                         (PIP_LSUo_INFO_pc),
    .RUo_VADDR                      (PIP_LSUo_DATA_data2),
    .RUo_DATA                       (PIP_LSUo_DATA_data1),
    .RUi_ready                      (PIP_LSUi_FC_ready)

);
endmodule

